;(function(undefined) {
    "use strict"
    var _global;

    var raycaster;
    var _center;
    var rayList;
    var targetList;
    var _lastTarget;

    function Gazer(){
        this._initiate();
    }

    Gazer.prototype = {
        
        _initiate : function() {
            // 初始化射线发射源
            raycaster = new THREE.Raycaster();
            _center = new THREE.Vector2();
            rayList = {},
            targetList = [];
            _lastTarget = null;
        },

        /** 物体绑定gaze事件的公用方法
         * @param {THREE.Object3D} target 监听的3d网格
         * @param {String} eventType 事件类型 
         * @param {Function} callback 事件回调
         **/
        on : function(target, eventType, callback) {
            const noop = () => {};
            // target首次绑定事件，则创建监听对象，加入raylist监听列表，并将三个基本事件的回调初始为空方法
            if (!rayList[target.id]) rayList[target.id] = { target, gazeEnter: noop, gazeTrigger: noop, gazeLeave: noop };
            // 根据传入的 eventType与callback更新事件回调
            rayList[target.id][eventType] = callback;
            targetList = Object.keys(rayList).map(key => rayList[key].target);
        },

        off : function(target) {
            delete rayList[target.id];
            targetList = Object.keys(rayList).map(key => rayList[key].target);
        },

        update : function(camera, delta) {
            if (targetList.length <= 0) return;
            //更新射线位置
            raycaster.setFromCamera(_center,camera);
            const intersects = raycaster.intersectObjects(targetList);
            if (intersects.length > 0) { // 当前帧射线击中物体
                const currentTarget = intersects[0].object;
                if (_lastTarget) { // 上一帧射线击中物体
                    if (_lastTarget.id !== currentTarget.id) { // 上一帧射线击中物体与当前帧不同
                        rayList[_lastTarget.id].gazeLeave(); 
                        rayList[currentTarget.id].gazeEnter();
                    }
                } else { // 上一帧射线未击中物体
                    rayList[currentTarget.id].gazeEnter(); // 触发当前帧物体的gazeEnter事件
                }
                rayList[currentTarget.id].gazeTrigger(delta); // 当前帧射线击中物体，触发物体的gazeTrigger事件
                _lastTarget = currentTarget;
            } else { // 当前帧我击中物体
                if ( _lastTarget ) rayList[_lastTarget.id].gazeLeave(); // 触发上一帧物体gazeLeave
                _lastTarget = null;
            }
        }
    }


    // 最后将插件对象暴露给全局对象
    _global = (function(){ return this || (0, eval)('this'); }());
    if (typeof module !== "undefined" && module.exports) {
         module.exports = Gazer;
    } else if (typeof define === "function" && define.amd) {
        define(function(){return Gazer;});
    } else {
        !('Gazer' in _global) && (_global.Gazer = Gazer);
    }
}());